/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.escom.healthlc.controller;

import com.escom.healthlc.business.PacienteBusiness;
import com.escom.healthlc.entidad.MedicoVO;
import com.escom.healthlc.entidad.PacienteVO;
import com.escom.healthlc.entidad.ParentescoVO;
import com.escom.healthlc.entidad.PersonaVO;
import com.escom.healthlc.utils.Constantes;
import com.escom.healthlc.utils.LazySorterPaciente;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Carlos
 */
@ManagedBean(name = "PacienteController")
@ViewScoped
public class PacienteController {

    private static final Logger logger = LoggerFactory.getLogger(PacienteController.class);

    private PacienteVO pacienteCreate;
    private PacienteVO pacienteSelect;
    private MedicoVO medicoCurrent;
    private String idPacienteParam;
    private String maxDate;
    private List<PacienteVO> pacienteConsulta;
    private LazyDataModel<PacienteVO> pacienteLazyModel;
    private boolean renderPanelAlta;
    private boolean renderPanelConsulta;
    private boolean pageComplete;

    @ManagedProperty("#{PacienteBusiness}")
    private transient PacienteBusiness pacienteBusiness;

    public PacienteController() {
    }

    @PostConstruct
    private void initPacienteController() {
        getUsuarioSession();
        executeLimpiarObjects(null);
    }

    public void executeCrearPaciente(ActionEvent acEvt) {
        logger.debug("executeCrearPaciente");
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        pacienteBusiness.crearPaciente(pacienteCreate, medicoCurrent.getIdMedico());
        int estado = pacienteBusiness.getEstado();
        String messageEstado = pacienteBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);
    }

    public void executeConsultarPaciente(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        pacienteConsulta = pacienteBusiness.consultarPaciente(medicoCurrent);
        crearLazyModelPaciente();
        int estado = pacienteBusiness.getEstado();
        String messageEstado = pacienteBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeChangeToRetrieve();
    }

    public void executeActualizarPaciente(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        pacienteBusiness.actualizarPaciente(pacienteSelect);
        int estado = pacienteBusiness.getEstado();
        String messageEstado = pacienteBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);
    }

    public void executeEliminarPaciente(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        pacienteBusiness.eliminarPaciente(pacienteSelect);
        int estado = pacienteBusiness.getEstado();
        String messageEstado = pacienteBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObjects(acEvt);
    }

    public void executeChangeToCreate() {
        renderPanelAlta = true;
        renderPanelConsulta = false;
    }

    public void executeChangeToRetrieve() {
        renderPanelAlta = false;
        renderPanelConsulta = true;
    }

    public void onRowSelect(SelectEvent seEvt) {
        pacienteSelect = (PacienteVO) seEvt.getObject();
    }

    public void executeLimpiarObjects(ActionEvent acEvt) {
        pacienteSelect = new PacienteVO();
        idPacienteParam = "";
        pacienteConsulta = new ArrayList();
        pacienteCreate = new PacienteVO();
        renderPanelAlta = false;
        renderPanelConsulta = false;
    }

    public void listenerIdPaciente(PacienteVO paciente) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext.getSessionMap().put("idPacienteParam", paciente);
    }

    public void getUsuarioSession() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
        HttpSession httpSession = request.getSession(true);
        medicoCurrent = (MedicoVO) httpSession.getAttribute("usuarioActivio");
    }

    public void renderView(ComponentSystemEvent event) {
        if (!pageComplete) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            FacesMessage facesMessage;
            ExternalContext externalContext = facesContext.getExternalContext();
            Map<String, String> requestParameterMap = externalContext.getRequestParameterMap();
            String isSelect = (String) requestParameterMap.get("select");
            logger.debug("isSelect {}", isSelect);
            if (isSelect != null && isSelect.equals("0")) {
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, "Alerta", "Debe seleccionar un paciente");
                facesContext.addMessage(null, facesMessage);
            }
            pageComplete = true;
        }
    }

    private void crearLazyModelPaciente() {
        pacienteLazyModel = new LazyDataModel<PacienteVO>() {
            List<PacienteVO> datasource = pacienteConsulta;

            @Override
            public PacienteVO getRowData(String rowKey) {
                for (PacienteVO paciente : datasource) {
                    if (paciente.getIdPaciente().equals(rowKey)) {
                        return paciente;
                    }
                }
                return null;
            }

            @Override
            public List<PacienteVO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                List<PacienteVO> data = new ArrayList<PacienteVO>();

                //filter  
                for (PacienteVO paciente : datasource) {
                    boolean match = true;
                    for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                        try {
                            String filterProperty = it.next();
                            Field field;
                            String filterValue = "";
                            String fieldValue;
                            if (filterProperty.contains("nombre") || filterProperty.contains("apPaterno")) {
                                filterValue = filters.get(filterProperty);
                                PersonaVO persona = paciente;
                                field = persona.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(persona));
                            } else {
                                filterValue = filters.get(filterProperty);
                                field = paciente.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(paciente));
                            }

                            if (filterValue == null || fieldValue.contains(filterValue)) {
                                match = true;
                            } else {
                                match = false;
                                break;
                            }
                        } catch (Exception e) {
                            match = false;
                        }
                    }

                    if (match) {
                        data.add(paciente);
                    }
                }

//                sort  
                if (sortField != null) {
                    Collections.sort(data, new LazySorterPaciente(sortField, sortOrder));
                }
                if (sortField == null) {
                    sortField = "defaultSortField";
                }
                //rowCount  
                int dataSize = data.size();
                this.setRowCount(dataSize);

                //paginate  
                if (dataSize > pageSize) {
                    try {
                        return data.subList(first, first + pageSize);
                    } catch (IndexOutOfBoundsException e) {
                        return data.subList(first, first + (dataSize % pageSize));
                    }
                } else {
                    return data;
                }
            }

            @Override
            public Object getRowKey(PacienteVO t) {
                return t.getIdPaciente();
            }
        };
    }

    public void setPacienteBusiness(PacienteBusiness pacienteBusiness) {
        this.pacienteBusiness = pacienteBusiness;
    }

    public PacienteVO getPacienteCreate() {
        return pacienteCreate;
    }

    public void setPacienteCreate(PacienteVO pacienteCreate) {
        this.pacienteCreate = pacienteCreate;
    }

    public PacienteVO getPacienteSelect() {
        return pacienteSelect;
    }

    public void setPacienteSelect(PacienteVO pacienteSelect) {
        this.pacienteSelect = pacienteSelect;
    }

    public LazyDataModel<PacienteVO> getPacienteLazyModel() {
        return pacienteLazyModel;
    }

    public String getIdPacienteParam() {
        return idPacienteParam;
    }

    public void setIdPacienteParam(String idPacienteParam) {
        this.idPacienteParam = idPacienteParam;
    }

    public void setPacienteLazyModel(LazyDataModel<PacienteVO> pacienteLazyModel) {
        this.pacienteLazyModel = pacienteLazyModel;
    }

    public boolean isRenderPanelAlta() {
        return renderPanelAlta;
    }

    public void setRenderPanelAlta(boolean renderPanelAlta) {
        this.renderPanelAlta = renderPanelAlta;
    }

    public boolean isRenderPanelConsulta() {
        return renderPanelConsulta;
    }

    public void setRenderPanelConsulta(boolean renderPanelConsulta) {
        this.renderPanelConsulta = renderPanelConsulta;
    }

    public String getMaxDate() {
        Calendar instance = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        maxDate = simpleDateFormat.format(instance.getTime());
        return maxDate;
    }

    public void setMaxDate(String maxDate) {
        this.maxDate = maxDate;
    }

}
